package cn.lll.vuehouse.aop;



import cn.lll.vuehouse.annotations.LogOperation;
import cn.lll.vuehouse.entity.Loginfo;
import cn.lll.vuehouse.service.LoginfoService;
import cn.lll.vuehouse.utils.IpUtil;
import cn.lll.vuehouse.utils.JWTUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;




//使用Spring AOP实现的日志切面类。
// 它使用@Aspect注解标记为切面类，并使用@Pointcut注解定义切入点，即被@LogOperation注解标记的方法。
// 在切入点方法执行前后，使用@Around注解定义环绕通知方法，通过ProceedingJoinPoint参数获取方法的参数、注解信息、请求信息等，
// 封装成LogInfo对象并保存到数据库中。其中，LogOperation是自定义的注解，用于标记需要记录日志的方法。
// mLogInfoService是一个服务类，用于保存LogInfo对象到数据库中。
@Component
@Aspect
public class LogAspect {

    @Autowired
    private LoginfoService loginfoService;


    @Pointcut("@annotation(cn.lll.vuehouse.annotations.LogOperation)")
    public void pointcut(){

    }
    @Around("pointcut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        Object proceed = null;

        try {
            proceed = proceedingJoinPoint.proceed();
            //获取日志信息   username  IP  url  model  description  args
            //args
            Object[] args = proceedingJoinPoint.getArgs();
            String strArgs = StringUtils.arrayToCommaDelimitedString(args);

            //model   description
            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = signature.getMethod();

            LogOperation annotation = method.getAnnotation(LogOperation.class);
            String description = annotation.description().getDescription();
            String model = annotation.model();

            //username  ip    url   ->request

            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();

            String token = request.getHeader("token");
            String username = (String) JWTUtil.getClaim(token).get("username");


            String uri = request.getRequestURI();
            String ip = IpUtil.getRequestClientRealIp(request);


            //封装日志参数

            Loginfo logInfo = new Loginfo();

            logInfo.setUsername(username);


            logInfo.setParams(strArgs);
            logInfo.setModel(model);
            logInfo.setIp(ip);
            logInfo.setUrl(uri);
            logInfo.setDescription(description);
            logInfo.setCreateTime(new Date());


            loginfoService.save(logInfo);

        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }


//    @Before("pointcut()")
//    public Object beforeAdvice(ProceedingJoinPoint proceedingJoinPoint){
//        Object proceed = null;
//
//        try {
//            proceed = proceedingJoinPoint.proceed();
//            //获取日志信息   username  IP  url  model  description  args
//            //args
//            Object[] args = proceedingJoinPoint.getArgs();
//            String strArgs = StringUtils.arrayToCommaDelimitedString(args);
//
//            //model   description
//            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
//            Method method = signature.getMethod();
//
//            LogOperation annotation = method.getAnnotation(LogOperation.class);
//            String description = annotation.description().getDescription();
//            String model = annotation.model();
//
//            //username  ip    url   ->request
//
//            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//            HttpServletRequest request = requestAttributes.getRequest();
//
//            String token = request.getHeader("token");
//            String username = (String) JWTUtil.getClaim(token).get("username");
//
//
//            String uri = request.getRequestURI();
//            String ip = IpUtil.getIp(request);
//
//
//            //封装日志参数
//
//            LogInfo logInfo = new LogInfo();
//            logInfo.setUsername(username);
//            logInfo.setParams(strArgs);
//            logInfo.setModel(model);
//            logInfo.setIp(ip);
//            logInfo.setUrl(uri);
//            logInfo.setDescription(description);
//            logInfo.setCreateTime(new Date());
//
//
//            logInfoService.save(logInfo);
//
//        } catch (Throwable throwable) {
//            throwable.printStackTrace();
//        }
//        return proceed;
//    }


}

